
/**
 * 注解定义Bean，其中的字段属性：
 * 1）普通类型：直接@Value赋值
 * 2）类：属性注入/构造器注入/setter注入
 *
 * 通过属性文件配置数据的方式之一： @Value，可以使用SpEL
 *               properties                yaml
 * 基本数据           ok                     ok
 * 集合数据           ok，仅支持单行表达        ok，仅支持单行表达
 *
 * 属性文件读取的三种方式：
 * 1.Enviroment.getProperty:只能读取默认的application配置文件
 * 2.@Value:逐个字段赋值，
 * 3.@ConfigurationProperties:整个对象赋值，属性必须同名，必须有setter
 *其中2、3方式可以用@PropertySource来指定其它配置文件
 */
package com.example.demospringbootbean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
@Scope("singleton")    //或者prototype
//@ConfigurationProperties("test")
public class ClassBB {

    @Value("wangwu")       //简单数值，通过反射实现赋值
    private String name;
    /*替代
    @Value("wangwu")       //简单数值
    public void setName(String name) {
        this.name = name;
    }*/

    @Value("#{20-2}")      //SpEL表达式
    private int age;

    @Value("${person.phone}")   //属性配置文件中person.phone属性的值
    private String phone;
    public void setPhone(String phone) {
        this.phone = phone;
    }

        @Value("${test.list}")
//      @Value("#{'${test.list}'}")
      private String[] stringArr;
//      public void setStringArr(String[] stringArr) {
//        this.stringArr = stringArr;
//    }

    //@Value("aa,bb,cc")                                        //直接赋值
    @Value("${test.list}")
//     @Value("#{'${test.list}'}")    //从属性文件不同名字段赋值
    private List<String> stringList;                            //从属性文件同名字段赋值无需任何额外注解
    //自动赋时是需要setter，@Value赋值时需关闭
//    public void setStringList(List<String> list) {
//        this.stringList = list;
//    }


    //  @Value("topic1,topic2,topic3")                            //直接赋值
//      @Value("${test.set}")
//          @Value("#{'${test.set}'}")   //从属性文件不同名字段赋值
    private Set<String> stringSet;                                //从属性文件同名字段赋值无需任何额外注解
    //自动赋值时是需要setter，@Value赋值时需关闭
    public void setStringSet(Set<String> stringSet) {
        this.stringSet = stringSet;
    }

//    @Value("#{${test.map}}")                                   //从属性文件不同名字段赋值
    private Map<String, String> map;                            //从属性文件同名字段赋值无需任何额外注解
    //自动赋时是需要setter，@Value赋值时需关闭
//    public void setMap(Map<String, String> map) {
//        this.map = map;
//    }


    //属性注入
    @Autowired
    private ClassCC classCC;

    //构造器注入
    @Autowired
    public ClassBB(ClassCC classCC) {
        AppContextUtil.printlng("ClassBB constructor：构造器注入ClassCC到ClassBB中");
        this.classCC = classCC;
    }

    //Setter注入
    @Autowired
    public void setClassCC(ClassCC classCC) {
        AppContextUtil.printlng("setClassCC：Setter注入ClassCC到ClassBB中");
        this.classCC = classCC;
    }

    //Setter注入,工厂方法
//    @Autowired
//    public void setClassCC() {
//        AppContextUtil.printlng("setClassCC(工厂方法)：Setter注入ClassCC到ClassBB中");
//        this.classCC = ClassCCFactory1.getClassFromStaticFactory();
////        this.classCC = new ClassCCFactory1().getClassFromInstanceFactory();
//    }

    public ClassBB() {
    }


    public void showInfo() {
        AppContextUtil.printlnr("name=" + name + ";age=" + age + ";phone=" + phone + ";ClassCC=" + classCC);
    }


    @PostConstruct  //相当于XML中的 init-method
    public void myInit() {
        System.out.println("调用<bean>的init回调方法： @PostConstruct ");
    }

    @PreDestroy    //相当于XML中的 destroy-method
    public void myDestory() {
        System.out.println("调用<bean>的destroy回调方法：@PreDestroy");
    }

    public void showCollection() {
        AppContextUtil.printlnr("stringList=" + stringList + ";stringSet=" + stringSet + ";map=" + map);
        if (stringArr!= null)  for (String x : stringArr) AppContextUtil.printlnr(x);
    }
}
